import {Button, Checkbox, Form, Input, InputNumber, UploadFile} from "antd";
import {ColProps} from "antd/es/grid/col";
import React, {BaseSyntheticEvent, ChangeEvent, useEffect} from "react";
import {Radio} from 'antd';
import {SizeType} from "antd/es/config-provider/SizeContext";
import {useForm} from "antd/es/form/Form";
import {FormInstance} from "antd/es/form/hooks/useForm";
import {RadioChangeEvent} from "antd/es/radio/interface";
import GlobalUpload from "../GlobalUpload";
import {UploadListType} from "antd/es/upload/interface";
import {Callbacks} from "rc-field-form/lib/interface";

type LayoutType = "horizontal" | "vertical" | "inline";// 水平、垂直、内联

type FormItemType = "password" | "text" | "number" | "textArea" | "checkbox" | "radio" | "upload";// 表单项的类型

// 表单数据类型
export interface FromListType {
    label: string,
    name: string,
    rules?: any[],// 规则校验
    type: FormItemType,// 输入内容设置
    radioData?: Array<{ value: string | number, label: string }>// 单选项
    wrapperCol?: ColProps,// 布局配置
    placeholder?: string,// 显示值
    maxLength?: number,// 字数限制
    minLength?: number,
    CheckComponent?: (() => JSX.Element) | undefined,// check内置组件
    disabled?: Boolean,// 是否禁用
    formItemStyle?: React.CSSProperties,// 行样式
    className?: string,// 表单组件内置类
    fileList?: UploadFile[],//上传列表
    setFileList?: any,//上传事件
    //上传样式
    uploadStyleType?: UploadListType
}

// 组件传值操作
interface Props {
    className?: string,// 父类
    style?: HTMLStyleElement,// 样式
    formList: Array<FromListType>,
    // form:FormInstance<any>,// 表单实例
    layout?: LayoutType,// 表单布局，label和输入框的区别
    wrapperCol?: ColProps,// 放置
    onReset?: () => void,//重置事件
    configText?: string,// 确定文字
    btnStyle?: React.CSSProperties,// 按钮布局样式
    isReset?: boolean,// 是否需要reset
    size?: SizeType,//控制大小
    setForm?: any,
    initialValues?: any//赋值表单
    onFinish: (values: any) => void
}

// 表单再封装
const FormComtent = (props: Props) => {
    const {
        className = "",
        style = {},
        // form,
        layout = 'horizontal',
        formList = [],
        onFinish,
        wrapperCol = {offset: 8, span: 16},
        configText = "确定",
        btnStyle,
        isReset = false,
        size = "large",
        setForm = null,
        initialValues = {}
    } = props;
    const [form] = useForm();

    // 设置 form 实例的函数
    const setFormInstance = () => {
        if (form) {
            setForm(form);
        }
    };

    // 在初始渲染时调用设置 form 实例的函数
    useEffect(() => {
        if (setForm !== null) {
            setFormInstance();
        }
    }, []);
    return (
        <div className={className} style={style}>
            <Form form={form} layout={layout} size={size} onFinish={onFinish}
                  initialValues={initialValues}>
                {
                    formList.length ? formList.map((v, i) => {
                        return (
                            <Form.Item
                                key={v.name}
                                rules={v?.rules || []}
                                label={v.label}
                                name={v.name}
                                style={v.formItemStyle}
                                className={v.className}
                                wrapperCol={v.wrapperCol}>
                                <FormItemComtent v={v} form={form}/>
                            </Form.Item>
                        )
                    }) : null
                }
                <Form.Item wrapperCol={wrapperCol} style={btnStyle}>
                    <Button type="primary"
                            htmlType="submit"
                            style={{marginRight: '20px'}}
                            size={size}>
                        {configText}
                    </Button>
                    {
                        isReset ? (
                            <Button htmlType="button" onClick={() => form.resetFields()} size={size}>
                                重置
                            </Button>
                        ) : null
                    }

                </Form.Item>
            </Form>
        </div>
    )
};

export default FormComtent;

interface ItemProps {
    v: FromListType,
    form: FormInstance<any>
}

const FormItemComtent = ({v, form}: ItemProps) => {
    const CheckComponent: (() => JSX.Element) | undefined = v.CheckComponent;
    const initValue = form?.getFieldValue(v.name);
    const onChange = (e: BaseSyntheticEvent | RadioChangeEvent) => {
        form?.setFieldsValue({[v.name]: e.target.value});
    };
    // 输入
    if (v.type === 'text') {
        return (<Input placeholder={v.placeholder}
                       maxLength={v.maxLength}
                       minLength={v.minLength} value={initValue}
                       onChange={onChange}/>)
    }
    // 文本域
    if (v.type === 'textArea') {
        return (<Input.TextArea placeholder={v.placeholder}
                                maxLength={v.maxLength}
                                value={initValue}
                                onChange={onChange}
        />)
    }
    // 选择项,自定义组件
    if (v.type === "checkbox") {
        return (
            <div style={{display: "flex", alignItems: "center", justifyContent: "space-between"}}>
                <Checkbox checked={initValue || false}
                          onChange={e => form?.setFieldsValue({[v.name]: e.target.checked})}>
                    {v.placeholder ? v.placeholder : null}
                </Checkbox>
                {
                    CheckComponent ? <CheckComponent/> : null
                }
            </div>
        )
    }
    // 数字
    if (v.type === "number") {
        return (
            <InputNumber value={Number(initValue)}
                         placeholder={v.placeholder}
                         onChange={e => form?.setFieldsValue({[v.name]: e})}
            />
        )
    }
    // 密码
    if (v.type === 'password') {
        return (
            <Input.Password value={initValue}
                            placeholder={v.placeholder}
                            onChange={onChange}
            />
        )
    }
    // 单选
    if (v.type === "radio") {
        return (
            <div style={{display: "flex", alignItems: "center", justifyContent: "space-between"}}>
                <Radio.Group value={initValue} onChange={onChange}>
                    {
                        v?.radioData?.length ? v?.radioData.map(v => {
                            return (
                                <Radio key={v?.value} value={v?.value}>{v.label}</Radio>
                            )
                        }) : null
                    }
                </Radio.Group>
                {
                    CheckComponent ? <CheckComponent/> : null
                }
            </div>
        )
    }
    if (v.type === 'upload') {
        return (
            <GlobalUpload uploadStyleType={v.uploadStyleType} fileList={v?.fileList || []}
                          setFileList={v?.setFileList}/>
        )
    }
    return (
        <Input placeholder={v.placeholder}
               maxLength={v.maxLength}
               minLength={v.minLength}
               value={initValue}
               onChange={onChange}
        />
    )
}
